home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
526-550
/
disk_540
/
parm
/
parm_src.lzh
/
Parse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-28
|
8KB
|
364 lines
/*
* Parse.c - Copyright © 1990 by S.R. & P.C.
*
* Created: 16 Jun 1990
* Modified: 28 Jul 1991 18:22:05
*
* Make>> make
*/
#include "ParMBase.h"
extern struct Extended_MenuItem *AllocItem(struct ParMConfig *PCfg, char *itemstr);
extern BOOL AddMenu(struct ParMConfig *PCfg, char *str);
extern BOOL AddSubMenu(struct ParMConfig *PCfg, char *substr);
extern void EndSubMenu(struct ParMConfig *PCfg);
extern BOOL AddEntry(struct ParMConfig *PCfg, char *item, char *cmd, char *args, char *win, char shortcut, char mode, long stk, short pri);
extern BOOL AddParMEvent(struct Window *Win, USHORT Code, USHORT Qual, USHORT Flags);
struct StaticData {
char *FileBuffer, *CurrentLine, *NextLine, *Byte, *LastByte;
short LineNum;
char tok[200];
};
/***** local variables *****/
static char *KeyWordTab[] = {
NULL,
"ITEM",
"ARUN",
"RUN",
"SHELL",
"WB",
"CFG",
"WIN",
"PRI",
"STACK",
"MENU",
"SUBMENU",
"ENDSUBMENU",
"COLOR",
"CMDWIN",
"SHELLWIN",
"SHELLCMD",
"WAITCMD",
"TMPDIR",
"SHORTCUTQUAL",
"ACTIVATEKEY",
"PASSTHROUGH",
"SCREENTOFRONT",
"NOCHECK"
};
/* status */
#define STAT_BEGIN 0
#define STAT_MENU 1
#define STAT_SUBMENU 2
#define STAT_ITEM 4
/* add the position of the error to the error message */
static void Err(struct ParMConfig *PCfg, struct StaticData *SD, char *msg)
{
SimpleRequest(PCfg->ReqTitle, "%s\nLine %d, Char %ld", msg, SD->LineNum, SD->Byte-SD->CurrentLine+1);
}
#define SYNTAX(msg) { Err(PCfg, SD, msg); return FALSE; }
/*
* Parse a line that may contain semicolons. Backslash ('\') is the override
* char. This function is called from ParseConfig() and from Command().
*/
void ParseLine(char *cmd)
{
struct ParMBase *ParMBase;
char *s,*d,c;
s = d = cmd;
while (c = *d++ = *s++) {
if (c == '\\')
*(d-1) = *s++;
else if (c == ';')
*(d-1) = '\n';
}
}
static BOOL get_line(struct StaticData *SD)
{
register char *s,c;
s = SD->CurrentLine = SD->NextLine;
if (!*s)
return FALSE;
while ((c = *s++) != 10 && c);
if (c)
*(s-1) = '\0';
SD->NextLine = s;
SD->LineNum++;
SD->Byte = SD->CurrentLine;
return TRUE;
}
/*
* b is a register variable used to replace global Byte pointer in
* get_token() body. Then, Byte must be restored before leaving.
*/
static char get_token(struct StaticData *SD)
{
register char *p, *b, c;
short i;
char quote;
b = SD->Byte;
while ((c = *b) == ' ' || c == '\t')
b++; /* skip extra spaces */
if (c == '#') /* comment */
return 0;
SD->LastByte = b; /* save address of next token */
if (c < 32 || c == '{' || c == '}') {
SD->Byte = (c) ? b+1 : b; /* prevent skipping of sentinel */
return c; /* '{', '}', '\0', or invalid char */
}
/* scan string */
p = SD->tok;
if (c == '"') {
b++;
quote = TRUE;
}
else
quote = FALSE;
while ((quote && *b != '"' && *b) || (!quote && *b > 32 && *b != ';'))
*p++ = *b++;
*p = '\0';
if (quote)
b++; /* skip closing '"' */
for (i = 1; i <= MAX_KEYWORD; i++) {
if (!Strcmp(SD->tok, KeyWordTab[i]))
break; /* arp Strcmp() is not case sensitive */
}
SD->Byte = b;
return i;
}
static BOOL ParseConfig(struct ParMConfig *PCfg, struct StaticData *SD)
{
char t, shortcut, mode;
long stack;
short pri, i;
USHORT status = STAT_BEGIN, Flags, Key[2];
char *args, *cmd, *win;
char itemstr[80], cmdstr[100], winstr[80];
FreeMenus(PCfg);
while(get_line(SD)) {
switch (t = get_token(SD)) {
case 0: /* allow empty lines */
break;
case TOK_MENU:
if (!(status & (STAT_MENU | STAT_ITEM)) && status != STAT_BEGIN)
SYNTAX("Unexpected MENU")
status = STAT_MENU;
if (get_token(SD))
AddMenu(PCfg, SD->tok);
else
SYNTAX("Unexpected end of line");
break;
case TOK_SUBMENU:
if (!(status & STAT_MENU) || (status & STAT_SUBMENU))
SYNTAX("Unexpected SUBMENU")
status = STAT_SUBMENU;
if (get_token(SD))
AddSubMenu(PCfg, SD->tok);
else
SYNTAX("Unexpected end of line");
break;
case TOK_ENDSUBMENU:
if (!(status & STAT_SUBMENU) || !(status & STAT_ITEM))
SYNTAX("Unexpected ENDSUBMENU")
PCfg->CurrentItem = &PCfg->CurrentSubMenu->NextItem;
status = STAT_MENU | STAT_ITEM;
break;
case TOK_ITEM:
if (status == STAT_BEGIN)
SYNTAX("Unexpected ITEM")
status |= STAT_ITEM;
shortcut = pri = 0;
stack = PCfg->DefaultStack;
win = args = NULL;
cmd = cmdstr;
if (get_token(SD) == '{') { /* command char */
shortcut = *SD->Byte++;
if (get_token(SD) != '}')
SYNTAX("Missing closing '}'");
get_token(SD);
}
strcpy(itemstr, SD->tok);
switch (mode = get_token(SD)) {
case TOK_WB:
stack = 0; /* Tell WBRun to take icon stack as default */
case TOK_SHELL:
case TOK_ARUN:
case TOK_RUN:
while ((t = get_token(SD))==TOK_WIN || t==TOK_STACK || t==TOK_PRI) {
if (!get_token(SD))
SYNTAX("Unexpected end of line")
switch (t) {
case TOK_WIN:
if (mode == TOK_RUN || mode == TOK_WB)
SYNTAX("WIN not allowed in this mode")
strcpy(winstr, SD->tok);
win = winstr;
break;
case TOK_STACK:
stack = Atol(SD->tok);
if (IoErr() || stack < 2000)
SYNTAX("Invalid stack")
break;
case TOK_PRI:
pri = Atol(SD->tok);
if (IoErr() || pri < -128 || pri > 127)
SYNTAX("Priority out of range")
break;
}
}
if (!t)
SYNTAX("Unexpected end of line")
switch(mode) {
case TOK_ARUN:
args = SD->Byte;
case TOK_WB:
strcpy(cmdstr, SD->tok);
break;
default: /* RUN & SHELL modes */
ParseLine(SD->LastByte);
cmd = SD->LastByte;
}
break;
case TOK_CFG:
if (!get_token(SD))
SYNTAX("Unexpected end of line")
strcpy(cmdstr, SD->tok);
break;
default:
SYNTAX("WB, ARUN, RUN, SHELL or CFG Expected")
}
if (!AddEntry(PCfg, itemstr, cmd, args, win, shortcut, mode, stack, pri))
return FALSE;
break;
case TOK_ACTIVATEKEY:
Flags = 0;
while ((t = get_token(SD))==TOK_PASSTHROUGH || t==TOK_SCREENTOFRONT || t==TOK_NOCHECK) {
switch (t) {
case TOK_PASSTHROUGH:
Flags |= PEF_PASSTHROUGH;
break;
case TOK_SCREENTOFRONT:
Flags |= PEF_SCREENTOFRONT;
break;
case TOK_NOCHECK:
Flags |= PEF_NOCHECK;
break;
}
}
for( i=0 ; i<2 ; i++ ) {
if (t) {
Key[i] = Atol(SD->tok);
if (IoErr())
SYNTAX("Invalid Key")
}
else
SYNTAX("Unexpected end of line")
t = get_token(SD);
}
/* Key[0] = Qualifier, Key[1] = Code */
if (!AddParMEvent(PCfg->Win, Key[1], Key[0], Flags))
Err(PCfg, SD, "Key already used");
break;
case TOK_STR:
SYNTAX("Keyword expected")
break;
default:
if (get_token(SD)) {
switch(t) {
case TOK_COLOR:
/* control if blockpen and detailpen are different */
PCfg->MenuPen = ((PCfg->MenuPen = Atol(SD->tok)) == PCfg->Win->BlockPen) ? PCfg->Win->DetailPen : PCfg->MenuPen;
break;
case TOK_CMDWIN:
strcpy(PCfg->CmdWindow, SD->tok);
break;
case TOK_SHELLWIN:
strcpy(PCfg->ShellWindow, SD->tok);
break;
case TOK_SHELLCMD:
strcpy(PCfg->ShellCmd, SD->LastByte);
break;
case TOK_WAITCMD:
strcpy(PCfg->WaitCmd, SD->LastByte);
break;
case TOK_TMPDIR:
strcpy(PCfg->TmpDir, SD->tok);
break;
case TOK_SHORTCUTQUAL:
PCfg->ShortCutQual = (USHORT)Atol(SD->tok);
if (IoErr()) {
PCfg->ShortCutQual = 0;
SYNTAX("Invalid qualifier");
}
break;
}
}
else
SYNTAX("Missing argument")
}
}
return TRUE;
}
long ParseMenus(struct ParMConfig *PCfg)
{
struct ParMBase *ParMBase;
struct StaticData StaticData;
BPTR cfg;
long FileSize;
BOOL stat;
BOOL pb = TRUE;
if (cfg = Open(PCfg->CurCfg, MODE_OLDFILE)) {
Seek(cfg, 0, OFFSET_END);
if ((FileSize = Seek(cfg, 0, OFFSET_BEGINNING)) > 0) {
if (StaticData.FileBuffer = AllocMem(FileSize+1, MEMF_PUBLIC|MEMF_CLEAR)) {
if (Read(cfg, StaticData.FileBuffer, FileSize) == FileSize) {
StaticData.NextLine = StaticData.FileBuffer;
StaticData.LineNum = 0;
stat = ParseConfig(PCfg, &StaticData);
CleanUp(PCfg->LinkMenu->NextMenu, PCfg->LinkMenu->LeftEdge + PCfg->LinkMenu->Width, PCfg->ItemHeight);
pb = FALSE;
}
Close(cfg);
FreeMem(StaticData.FileBuffer, FileSize+1);
}
}
}
if (pb) {
SimpleRequest(PCfg->ReqTitle, "Couldn't open/read \"%s\"", PCfg->CurCfg);
return FALSE;
}
return stat;
}